package com.kitty.game.pet.handler.upgrade;

import com.kitty.game.pet.model.Pet;
import com.kitty.game.role.model.Role;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.common.utils.SpringUtils;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.enter.RespUpdate;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.pet.PetDataPool;
import com.kitty.game.pet.PetType;
import com.kitty.game.pet.bean.PetObject;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.utils.Arith;
import com.kitty.mina.message.MessagePusher;
import com.kitty.game.fight.service.CountService;
import com.kitty.game.role.service.RoleService;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

//后加
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public abstract class UpgradePetHandler {
    @Autowired
    protected EquipService equipService;
    @Autowired
    protected PetService petService;
    @Autowired
    protected RoleService roleService;

    protected Logger logger = LoggerFactory.getLogger(getClass());


    private static int BAIGUOER_PET_COST_REQ_LEVEL = 70;
    private static List<Double> perList = Arrays.asList(0.2, 0.3, 0.5);
    static List<String> ECLOSION_RANK = Arrays.asList("初阶", "中阶", "高阶");
    static final String ERROR_ITEM = "请放入正确的材料。";
    static final String NOT_ENCHANT = "该宠物还未点化，无法开启羽化。";
    static final String NOT_OPEN_ECLOSION = "该宠物还未开启羽化，无法提升灵气。";
    static final String ERROR_OPER_MSG = "你的#Y{0}#n已经开启{1}了。";

    public abstract String acceptUpgradePet(Role role, Pet pet, String ids, String itemPos, String costType, String otherPetPos);

    /**
     * 取点化最大灵气
     */
    int getEnchantMaxNimbus(Pet pet) {
        PetObject petObject = PetDataPool.getPetObject(pet.getName());
        int level = petObject.getLevel_req();

        /**如果服务器有下发最大灵气上限则使用服务器的下发值*/
        if (pet.getName().equals("白果儿")) {
            if (pet.getEnchant_k() > 0) {
                return pet.getEnchant_k();
            }
            /**如果未进化过*/
            if (Strings.isEmpty(pet.getEvolveName())) {
                level = BAIGUOER_PET_COST_REQ_LEVEL;
            }
        }
        int totalNimbus = (int) (30 * Math.pow(level, 2));

        if (petObject.getPetType() == PetType.ELITE || petObject.getPetType() == PetType.EPIC) {
            totalNimbus = 400000;
        } else if (petObject.getPetType() == PetType.JINGGUAI) {
            totalNimbus = 300000;
        }
        return totalNimbus;
    }

    /**
     * 取宠物羽化最大值
     */
    int getEclosionMaxNimbus(Pet pet) {
        PetObject petObject = PetDataPool.getPetObject(pet.getName());
        int level = petObject.getLevel_req();
        if (pet.getEclosion_k() > 0) {
            return pet.getEclosion_k();
        }
        double per = perList.get(pet.getEclosion_rank());
        int rank = petObject.getPetType();
        if (rank == PetType.EPIC) {
            return (int) Math.floor(1400000 * per);
        } else if (rank == PetType.ELITE) {
            return (int) Math.floor(700000 * per);
        } else if (rank == PetType.JINGGUAI) {
            return (int) Math.floor(300000 * per);
        } else if (rank == PetType.JINIAN) {
            return (int) Math.floor(Math.floor(3000 * Math.pow(1, 0.85) + 39 * 3000) * per);
        } else {
            String petName = Strings.isEmpty(pet.getEvolveName()) ? pet.getName() : pet.getEvolveName();
            if (petName.equals("白果儿")) {
                level = BAIGUOER_PET_COST_REQ_LEVEL;
            }
            return (int) Math.floor(Math.floor(3000 * Math.pow(level, 0.85) + 39 * 3000) * per);
        }
    }

    /**
     * 获得物品转换的羽化灵气
     */
    int getEclosionNimbusByItems(Role role, List<RoleEquip> equips) {
        int nimbus = 0;
        for (RoleEquip equip : equips) {
            if (equip.getType().equals("法宝")) {
                nimbus += 1000000 / 5000;
            } else if (equip.getName().equals("羽化丹")) {
                nimbus += 3000;
            } else {
                if (equip.getType().equals("未鉴定装备")) {
                    int toNimbus = EquipDataPool.getEquipToNimbus(equip);
                    nimbus += Math.floor(toNimbus * (1 + 2 * 3) / 5.0 / 1000.0 / 5.0);
                } else {
                    nimbus += Math.floor(equip.queryPrice() / 1000.0 / 5.0 / 5.0);
                }
            }
            equipService.delEquipNum(role, equip, 1);
        }
        return nimbus;
    }

    /**
     * 获得物品转换的点化灵气
     */
    int getEnchantNimbusByItems(Role role, List<RoleEquip> equips) {
        int nimbus = 0;
        for (RoleEquip equip : equips) {
            if (equip.getType().equals("法宝")) {
                nimbus += 1000000 / 1000;
            } else if (equip.getName().equals("点化丹")) {
                nimbus += 6000;
            } else {
                if (equip.getType().equals("未鉴定装备")) {
                    int toNimbus = EquipDataPool.getEquipToNimbus(equip);
                    nimbus += Math.floor(toNimbus * (1 + 2 * 3) / 5.0 / 1000.0);
                } else {
                    nimbus += Math.floor(equip.queryPrice() / 1000.0 / 5.0);
                }
            }
            equipService.delEquipNum(role, equip, 1);
        }
        return nimbus;
    }


    /**
     * 宠物点化增加的属性
     */
    int addPetEnchantValue(int shapeBasic, Pet pet, int nimbus) {
        shapeBasic = Math.abs(shapeBasic);
        double totalNimbus = pet.getEnchant_k();
        double currNimbus = pet.getEnchant_v();
        double valueLocal = Math.floor(Arith.mul(Arith.div(Math.floor(Arith.mul(Arith.mul(0.3, Math.min(Arith.div(currNimbus, totalNimbus), 1.0)), 100.0)), 100.0), shapeBasic));
        double totalEff = Math.floor(Arith.mul(Arith.div(Math.floor(Arith.mul(Arith.mul(0.3, Math.min(Arith.div(currNimbus + nimbus, totalNimbus), 1.0)), 100.0)), 100.0), shapeBasic));
        return (int) Arith.sub(totalEff, valueLocal);
    }

    /**
     * 宠物羽化增加的属性
     */
    int addPetEclosionValue(int shapeBasic, Pet pet, String shapeType) {
        int rank = pet.getType();
        Map<Integer, Map<String, Double>> rateMap = new HashMap<>();
        Map<String, Double> epicRate = new HashMap<>();
        epicRate.put("phy", 0.5);
        epicRate.put("mag", 0.7);
        epicRate.put("speed", 0.45);
        epicRate.put("mana", 0.4);
        epicRate.put("life", 0.8);
        Map<String, Double> eliteRate = new HashMap<>();
        eliteRate.put("phy", 0.4);
        eliteRate.put("mag", 0.5);
        eliteRate.put("speed", 0.4);
        eliteRate.put("mana", 0.25);
        eliteRate.put("life", 0.6);
        Map<String, Double> otherRate = new HashMap<>();
        otherRate.put("phy", 0.2);
        otherRate.put("mag", 0.2);
        otherRate.put("speed", 0.3);
        otherRate.put("mana", 0.2);
        otherRate.put("life", 0.5);
        rateMap.put(4, epicRate);
        rateMap.put(3, eliteRate);
        rateMap.put(0, otherRate);
        List<Double> stageMap = Arrays.asList(0.0, 1.0 / 3.0, 2.0 / 3.0, 1.0);
        double rate = rateMap.get(0).get(shapeType);
        if (rank == 4) {//神兽
            rate = rateMap.get(4).get(shapeType);
        } else if (rank == 3) {
            rate = rateMap.get(3).get(shapeType);
        }
        shapeBasic = Math.abs(shapeBasic);
        int stage = pet.getEclosion_rank();
        double para1 = Math.floor(rate * stageMap.get(stage + 1) * 100000);
        double para2 = Math.floor(rate * stageMap.get(stage) * 100000);
        int retValue = (int) Math.floor(para1 / 100000 * shapeBasic);
        int beforeValue = (int) Math.floor(para2 / 100000 * shapeBasic);
        if (shapeBasic == 0 && stage + 1 > 3) {
            return 1;
        }
        return retValue - beforeValue;
    }

    /**幻化增加的属性*/
    int addMorphValue(Pet pet, String fieldName) {
        PetObject petObject = PetDataPool.getPetObject(pet.getName());
        int basic = petObject.getGrowInfo(false, fieldName).get("max");
//        int value = 0;
//        switch (fieldName) {
//            case "life":
//                value = petObject.getLife();
//                break;
//            case "mana":
//                value = petObject.getMana();
//                break;
//            case "speed":
//                value = petObject.getSpeed();
//                break;
//            case "phy":
//                value = petObject.getPhy_attack();
//                break;
//            case "mag":
//                value = petObject.getMag_attack();
//                break;
//        }
        int morphProgressMax = 3;
        if (pet.getType() == 3 || pet.getType() == 4) {
            morphProgressMax = 5;
        }
        int curr = pet.getMorphEffect().getOrDefault(fieldName + "_stat", 0);
        if (curr < morphProgressMax) {
            return 0;
        }
        double per = 0.06;
        //变异系数为8%   变异宠物的法功系数为12%   ,变异宠物不计算附加成长(神兽与变异宠物计算方式相同)
        if (pet.getType() == 3 || pet.getType() == 4) {
            if (fieldName.equals("mag")) {
                per = 0.12;
            } else {
                per = 0.08;
            }
//            basic = basic - petObject.getElitePetBasicAddByValue(value);
//            Todo 按道理神兽变异的附加成长应该 单独放一个地方 而不是放在基础成长里面 这样幻化的话就不能减附加的成长
        }
        return (int) Math.max(Math.floor(Arith.mul(basic, per)), 1);
    }

    /**
     * 刷新宠物的属性值
     */
    void refreshPetField(Role role, Pet pet) {
        CountService countService = SpringUtils.getBean(CountService.class);
        ArrayList<FiedValue> values = new ArrayList<>();
        values.add(new FiedValue(8, countService.countPetMaxDefense(pet)));
        values.add(new FiedValue(7, countService.countPetMaxLife(pet)));
        values.add(new FiedValue(12, countService.countPetMaxMana(pet)));
        values.add(new FiedValue(14, countService.countPetMaxSpeed(pet)));
        values.add(new FiedValue(3, countService.countPetMaxPhyPower(pet)));
        values.add(new FiedValue(10, countService.countPetMaxMagPower(pet)));
        RespUpdate respUpdate = new RespUpdate();
        respUpdate.setRoleId(pet.getId());
        respUpdate.setList(values);
        MessagePusher.pushMessage(role, respUpdate);
    }


    /**
     * 添加点化的属性
     */
    void setEnchantValue(Pet pet, int totalNimbus) {
        NutMap enchantMap = pet.getEnchantEffect();
        int addLife = addPetEnchantValue(pet.getLifeEffect(), pet, totalNimbus) + enchantMap.getInt("life", 0);
        int addMana = addPetEnchantValue(pet.getManaEffect(), pet, totalNimbus) + enchantMap.getInt("mana", 0);
        int addSpeed = addPetEnchantValue(pet.getSpeedEffect(), pet, totalNimbus) + enchantMap.getInt("speed", 0);
        int addPhy = addPetEnchantValue(pet.getPhyEffect(), pet, totalNimbus) + enchantMap.getInt("phy", 0);
        int addMag = addPetEnchantValue(pet.getMagEffect(), pet, totalNimbus) + enchantMap.getInt("mag", 0);
        enchantMap.put("life", addLife);
        enchantMap.put("mana", addMana);
        enchantMap.put("speed", addSpeed);
        enchantMap.put("phy", addPhy);
        enchantMap.put("mag", addMag);
        pet.setEnchantEffect(enchantMap);
    }


    /**
     * 添加羽化的属性 只有一个阶段完成的时候才加
     */
    void setEclosionValue(Pet pet) {
        NutMap effect = pet.getEclosionEffect();
        int addLife = addPetEclosionValue(pet.getLifeEffect(), pet, "life") + effect.getInt("life", 0);
        int addMana = addPetEclosionValue(pet.getManaEffect(), pet, "mana") + effect.getInt("mana", 0);
        int addSpeed = addPetEclosionValue(pet.getSpeedEffect(), pet, "speed") + effect.getInt("speed", 0);
        int addPhy = addPetEclosionValue(pet.getPhyEffect(), pet, "phy") + effect.getInt("phy", 0);
        int addMag = addPetEclosionValue(pet.getMagEffect(), pet, "mag") + effect.getInt("mag", 0);
        effect.put("life", addLife);
        effect.put("mana", addMana);
        effect.put("speed", addSpeed);
        effect.put("phy", addPhy);
        effect.put("mag", addMag);
        pet.setEclosionEffect(effect);
    }
}
